#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/shm.h>

#define MYPORT 8080
#define QUEUE 20
#define BUFFER_SIZE 16

int main(int argc, char *argv[])
{
    // 创建套接字描述符 ipv4 tcp 最后一位0也行
    int svrFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    // 定义  sockaddr_in
    struct sockaddr_in svraddr;
    svraddr.sin_family = AF_INET;                // ipv4
    svraddr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0
    svraddr.sin_port = htons(8080);            // PORT 7889

    // bind，成功返回0，出错返回-1
    if (bind(svrFd, (struct sockaddr *)&svraddr, sizeof(struct sockaddr)) == -1)
    {
        perror("bind error");
        exit(1);
    }

    /**
     * listen
     * param: fd queue     queue是阻塞队列, 具体什么原理还不清楚
     * return: 成功 0, 错误 -1
     */
    if (listen(svrFd, 20) == -1)
    {
        perror("listen error");
        exit(1);
    }

    // 客户端套接字
    struct sockaddr_in client_addr;
    socklen_t length = sizeof(client_addr);

    printf("wait accept----\n");
    /// 成功返回非负描述字，出错返回-1
    //  如果不需要知道客户端的信息, 可以 accept(svrFd,NULL, NULL);
    int cliFd = accept(svrFd, (struct sockaddr *)&client_addr, &length);
    if (cliFd < 0)
    {
        perror("connect");
        exit(1);
    }

    char rBuff[128] = {0};
    char wBuff[128] = {0};

    // 接受客户端传的数据
    // read(cliFd, buff, sizeof(buff));
    int rSize = recv(cliFd, rBuff, sizeof(rBuff), 0);
    if(rSize > 0){
        // 接受到的buff大小
    } else if(rSize == 0){
        // 客户端关闭
    } else{
        // 接受异常
    }
    printf("%d recv msg: %s\n", rSize, rBuff);

    // 业务逻辑
    strcpy(wBuff, "pong");
    // 发送数据给客户端
    // write(cliFd, buff, sizeof(buff));
    int wSize = send(cliFd, wBuff, sizeof(wBuff), 0);
    // wSize返回值同 rSize

    close(cliFd);
    close(svrFd);
    return 0;
}
